package ecmnext.server;

/***************************************************************/
/*                     SOFTWARE SECTION                        */
/***************************************************************/
/*
 * <p>Name: ECMNext</p>
 * <p>Description: Simulation of the platform of trading Software</p>
 * <p>Licence: General Public License</p>
 * <p>Organisation: EC Marseille</p>
 * <p>Persons involved in the project : groupe Plateforme de Trading</p>
 * <p>Current version: 1.0</p>
 */


/***************************************************************/
/*                       IMPORT SECTION                        */
/***************************************************************/

import java.io.*;


import java.awt.*;
import javax.swing.*;

import org.apache.log4j.*;
import ecmnext.business.*;
import ecmnext.server.gui.*;
import ecmnext.server.net.*;
import ecmnext.utils.*;
//import org.jdom.Element;
import org.jdom.Document;
import java.util.Properties;

/***************************************************************/
/*                   Server CLASS SECTION                      */
/***************************************************************/
/**
 * <p>Title: Server</p>
 * <p>Description: </p>
 * @author Xuewen YANG ET Antoine COUDERC
 * @version 0.9
 */
public class Server {

  public static int EXPERIMENT_STATE_SETUP = 0;
  public static int EXPERIMENT_STATE_RUNNING = 1;
  public static int EXPERIMENT_STATE_ENDED = 2;

  public static int SERVER_STATE_OFFLINE = 3;
  public static int SERVER_STATE_ONLINE = 4;

  boolean packFrame = true;

  /**
   * The server Frame
   */
  private GeneralServerFrame frame;

  private static int experimentState = 0; // value: EXPERIMENT_STATE_( SETUP | RUNNING | ENDED )
  private static int serverState = 3;     // value: SERVER_STATE_( ONLINE | OFFLINE )


  public static int getExperimentState() {
    return experimentState;
  }

  public static int getServerState() {
    return serverState;
  }

  public static void setServerState(int servState) {
    serverState = servState;
    if (servState == SERVER_STATE_ONLINE) {
      NetworkCore.setServerOnline();
    }
    else {
      /**
       * @todo implementer l'arret d'ecoute du serveur.
       */
      NetworkCore.setServerOffline();
      }
  }


  //Build Application
  public Server(String scenarioFile, boolean	graphicalMode) {

    //BusinessCore.init(); // -todo : non used?
    BusinessCore.setGeneralParameters(new GeneralParameterSetupGui(graphicalMode));

    experimentState = EXPERIMENT_STATE_SETUP;
    serverState = SERVER_STATE_OFFLINE;

    loadServerProperties();

    loadJessXModules();

    if (graphicalMode)
    	buildFrame();

    try
       {
         if (scenarioFile != "") {

           System.out.println("Il y a un fichier, chargement...");

           Document xmlDoc = Utils.readXmlFile(scenarioFile);

           BusinessCore.loadFromXml(xmlDoc.getRootElement(), frame);
         }
       }
     catch(Exception ex)
     {
     }
  }

  /**
   * <p>Loads all known modules, from the following locations: <br />
   * - modules/Operations<br />
   * - modules/Institutions<br />
   * - modules/Assets</p>
   */
  private void loadJessXModules() {
    Utils.logger.debug("Loading all available modules.");


    Utils.loadModules("ecmnext.business.operations.LimitOrder");
    Utils.loadModules("ecmnext.business.operations.DeleteOrder");
    Utils.loadModules("ecmnext.business.operations.MarketOrder");
    Utils.loadModules("ecmnext.business.operations.BestLimitOrder");

    Utils.loadModules("ecmnext.business.institutions.OrderMarket");

    Utils.loadModules("ecmnext.business.assets.Stock");

    Utils.logger.debug("All available modules loaded.");
  }

  private static final FileFilter filter = new FileFilter() {
    public boolean accept(File pathname) {
      if (pathname.isDirectory())return true;
      if (!pathname.isFile())return false;

      String path = pathname.getAbsolutePath();
      if (!path.endsWith(".class"))return false;
      if (path.indexOf('$') >= 0)return false;

      return true;
    }
  };


  /**
   * <p>Builds the main frame, by creating the frame object and placing it at the
   * center of the screen.</p>
   */
  private void buildFrame() {

    Utils.logger.info("Building frame...");
    frame = new ecmnext.server.gui.GeneralServerFrame();

    //Validate panels where preferred size is set
    if (packFrame) {
      frame.pack();
      Utils.logger.debug("Frame packed.");
    }
    else {
      frame.validate();
      Utils.logger.debug("Frame validated.");
    }
    //Center window
    Utils.logger.debug("Placing frame...");
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    Dimension frameSize = frame.getSize();
    if (frameSize.height > screenSize.height) {
      frameSize.height = screenSize.height;
    }
    if (frameSize.width > screenSize.width) {
      frameSize.width = screenSize.width;
    }
    frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
    Utils.logger.debug("Setting the frame visible.");
    frame.setVisible(true);
  }

  private void loadServerProperties() {
    //String path = System.getProperty("user.dir") + System.getProperty("file.separator") + Constants.SERVER_PROPERTIES_FILE;
    //Utils.logger.debug("Loading server properties from file: " + path);
    //Utils.loadApplicationProperties(path);

    Utils.logger.debug("Sets WaitingPort");
    Utils.SetApplicationProperties("ServerWaitingPort","6290");
  }

  public void startServer() {

  }

  //main method
    public final static String SERVER_LOG_FILE = "./server.log";

  public static void InitLogs() {

    File file = new File(SERVER_LOG_FILE);
    if (file.exists()) file.delete();

    //PropertyConfigurator.configure("log4j.server.properties");

    // Fill in a Property object
    Properties log4jconf = new Properties();

  // Use two appenders, one to log to console, another to log to a file
    log4jconf.setProperty("log4j.rootCategory", "debug, stdout, R");

  // Print only messages of priority DEBUG or higher for your category
    log4jconf.setProperty("log4j.category.your.category.name", "DEBUG");

  // Specifically inherit the priority level
    log4jconf.setProperty("log4j.category.your.category.name", "INHERITED");

  // First appender writes to console
    log4jconf.setProperty("log4j.appender.stdout",
                          "org.apache.log4j.ConsoleAppender");
    log4jconf.setProperty("log4j.appender.stdout.layout",
                          "org.apache.log4j.PatternLayout");

  // Pattern to output the caller's file name and line number.
    log4jconf.setProperty("log4j.appender.stdout.layout.ConversionPattern",
                          "%5p [%t] (%F:%L) - %m%n");

  // Second appender writes to a file
    log4jconf.setProperty("log4j.appender.R",
                          "org.apache.log4j.RollingFileAppender");
    log4jconf.setProperty("log4j.appender.R.File", SERVER_LOG_FILE);

  // Control the maximum log file size
    log4jconf.setProperty("log4j.appender.R.MaxFileSize", "500000KB");

  // Archive log files (one backup file here)
    log4jconf.setProperty("log4j.appender.R.MaxBackupIndex", "1");

    log4jconf.setProperty("log4j.appender.R.layout",
                          "org.apache.log4j.PatternLayout");
    log4jconf.setProperty("log4j.appender.R.layout.ConversionPattern",
                          "%r [%p] %m  [%t] (%F:%L) \r\n");

  // Set this configuration
    PropertyConfigurator.configure(log4jconf);

    Utils.logger.debug("Logging enabled. Starting logging...");
  }

   public static void main(String[] args) {

     InitLogs();

    try {
      Utils.logger.debug("Getting and setting look and feel...");
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch(Exception e) {
      Utils.logger.error("Error while loading look and feel: " + e.toString());
      e.printStackTrace();
    }

    Utils.logger.debug("Understanding Parameters");
    boolean	graphicalMode = true;
    String	xmlfile	= "";
    
    for(int i=0;i<args.length;i++) {

    	if (args[i] == "textmode")
    		graphicalMode = false;
    	
    	if (args[i].contains("xml"))
    		xmlfile = args[i];   	
    }
    
    Utils.logger.debug("Creating core object.");    
    	
    new Server( xmlfile, graphicalMode );
  }
}
